from django.shortcuts import render, redirect
from django.views import View
from django import http
from django.contrib.auth import authenticate
from django.db import DatabaseError
from django.contrib.auth import login, logout
from django import http
from django_redis import get_redis_connection
from django.contrib.auth.mixins import LoginRequiredMixin
import json
import re
import logging

from .models import User
from django.urls import reverse
from nxh_mall.utils.response_code import RETCODE
from nxh_mall.utils import response_code
from nxh_mall.utils.views import LoginRequiredJSONMixin
from celery_tasks.email.tasks import send_verify_email
from .utils import genrate_verify_email_url, check_verify_email_token

logger = logging.getLogger('django')


# Create your views here.

class AddressView(LoginRequiredMixin, View):
    def get(self, request):
        addresses = []
        return render(request, 'user_center_site.html', context={'address': addresses,'addresses':addresses})


class VerifyEmailView(View):
    def get(self, request):
        token = request.GET.get('token')
        if not token:
            return http.HttpResponseForbidden('缺少必要参数')
        # 从token中提取user
        user = check_verify_email_token(token)
        if not user:
            http.HttpResponseBadRequest('无效的token')

        #
        try:
            user.email_active = True
            user.save()
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '激活邮箱失败'})
        else:
            return redirect(reverse('users:user_center'))


class EmailView(LoginRequiredJSONMixin, View):
    def put(self, request):
        body = request.body.decode()
        body_json = json.loads(body)
        email = body_json.get('email')
        # 校验邮箱
        if not re.match(r'^[0-9a-zA-Z_]{0,19}@[0-9a-zA-Z]{1,13}\.[com,cn,net]{1,3}$', email):
            # if re.match(r'[0-9a-zA-Z_]{0,19}@163.com',text):
            return http.HttpResponseForbidden('参数email错误')

        try:
            request.user.email = email
            request.user.save()
        except Exception as e:
            logger.error(str(e))
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '添加邮箱失败'})

        verify_url = genrate_verify_email_url(user=request.user)
        logger.info(verify_url)
        # 发送验证邮件,调用delay地方法
        send_verify_email.delay(to_email=email, verify_url=verify_url)

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})


class UserCenterInfoView(View):
    def get(self, request):
        if request.user.is_authenticated:
            context = {'username': request.user.username,
                       'mobile': request.user.mobile,
                       'email': request.user.email,
                       'email_active': request.user.email_active

                       }
            return render(request, 'user_center_info.html', context)
        else:
            return render(request, 'login.html')
        # login_url = reverse('users:login')
        # redirect_field_name = reverse('users:user_center')
        # return render(request, 'user_center_info.html')


# 退出登录操作
class LoginOutView(View):
    def get(self, request):
        logout(request)
        response = http.JsonResponse({'code': RETCODE.OK})
        response.delete_cookie('username')

        # 退出登录后重定向到首页
        return response

    def delete(self, request):
        logout(request)
        # 退出登录后重定向到首页
        return http.JsonResponse({'code': RETCODE.OK})


# 登录操作
class LoginView(View):
    def get(self, request):
        return render(request, 'login.html')

    def post(self, request):
        # 用户登录逻辑
        body = request.body.decode('utf-8')
        json_body = json.loads(body)
        username = json_body.get('username')
        password = json_body.get('password')
        remembered = json_body.get('remembered', False)
        if not all([username, password]):
            return http.HttpResponseForbidden('缺少必传参数')
        if len(username) < 5 or len(username) > 20:
            return http.HttpResponseForbidden('用户名输入错误')
        if len(password) < 8 or len(password) > 20:
            return http.HttpResponseForbidden('密码输入错误')

        # 登录验证
        user = authenticate(username=username, password=password)
        if user is None:
            return http.JsonResponse({'code': 400, 'errmsg': '密码或者密码输入有误'})

        # 状态保持
        login(request, user)
        if remembered:
            # 设置好过期时间：默认两周，传NONE，单位是秒
            request.session.set_expiry(None)
        else:
            # 浏览器关闭登录失效
            request.session.set_expiry(0)
        next = request.GET.get('next')
        if next:
            print('重定向到next', next)
            # response = redirect(next)
        else:
            print('重定向到首页', next)

        response = http.JsonResponse({'code': RETCODE.OK, 'errmsg': '登录成功！'})
        response.set_cookie('username', username, max_age=3600 * 24 * 15)
        return response


class RegisterView(View):
    def get(self, request):

        return render(request, 'register.html')

    def post(self, request):
        body = request.body.decode('utf-8')
        json_body = json.loads(body)
        username = json_body.get('username', '')
        password = json_body.get('password', '')
        password2 = json_body.get('password2', '')
        mobile = json_body.get('mobile', '')
        sms_code = json_body.get('sms_code', '')
        allow = json_body.get('allow', False)
        # yanzhengxanshu
        if not all([username, password, password2, mobile, sms_code, allow]):
            return http.HttpResponseForbidden('请求错误')
        # 验证参数是否为空
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            return http.HttpResponseForbidden('请输入4-20的账号')

        # 验证参数是否为空
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return http.HttpResponseForbidden('请输入8-20的账号')

        # 密码输入是否一致
        if password != password2:
            return http.HttpResponseForbidden('两次密码输入不一致')

        # 检查手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('请输入正确的手机号码')
            # 验证短信验证码有效性
        if not allow:
            return http.HttpResponseForbidden('请勾选用户协议')

        redis_conn = get_redis_connection(alias='verify_code')
        sms_code_server = redis_conn.get('sms_code_%s' % mobile)
        if sms_code_server is None:
            data = {'register_errmsg': '短信验证码已失效',
                    'code': RETCODE.SMSCODERR,
                    }
            return http.JsonResponse(data)
        sms_code_server = sms_code_server.decode()
        if sms_code != sms_code_server:
            return http.JsonResponse(
                {'register_errmsg': '短信验证码输入错误', 'code': RETCODE.SMSCODERR})

        print('--------', json_body)
        # return render(request, 'index1.html', context={'register_errmsg': '注册失败'})

        # 保存数据模型
        try:
            # user = User.objects.create(username=username, password=password, mobile=mobile)
            # user.set_password(password) #设置密码加密保存
            user = User.objects.create_user(username=username, password=password, mobile=mobile)
        except DatabaseError as e:
            print(e)
            data = {'register_errmsg': '注册失败',
                    'code': 403,
                    }
            return http.JsonResponse(data)
            # return render(request, 'register.html',context={'register_errmsg':'注册失败'})

        # 状态保存，存储登录状态
        login(request, user=user)

        # return HttpResponse('注册成功！')
        data = {'register_errmsg': '',
                'code': RETCODE.OK,
                }
        response = http.JsonResponse(data)
        # cookies保存15天
        response.set_cookie('username', username, max_age=3600 * 24 * 15)

        return response
        # url = reverse('contents:index')

        # return HttpResponseRedirect(url, content=data)

        # return redirect('/index')


class UsernameCountView(View):

    def get(self, request, username):
        count = User.objects.filter(username=username).count()
        json_data = {'code': RETCODE.OK,
                     'errmsg': 'OK',
                     'count': count
                     }
        return http.JsonResponse(json_data)


class MobilesCountView(View):

    def get(self, request, mobile):
        count = User.objects.filter(mobile=mobile).count()
        json_data = {'code': RETCODE.OK,
                     'errmsg': 'OK',
                     'count': count
                     }
        return http.JsonResponse(json_data)
